package com.sudo.service.admin.service.impl;

import com.github.pagehelper.PageHelper;
import com.sudo.common.enums.SysServerStatus;
import com.sudo.common.enums.SysServerType;
import com.sudo.common.utils.PagedGridResult;
import com.sudo.dao.admin.entity.SysInfo;
import com.sudo.dao.admin.entity.SysServerNode;
import com.sudo.dao.admin.mapper.SysServerNodeMapper;
import com.sudo.dao.admin.model.bo.SysServerNodeUpdateBO;
import com.sudo.dao.admin.model.bo.SysServerNodeQueryBO;
import com.sudo.dao.admin.model.bo.SysServerNodeSaveBO;
import com.sudo.dao.admin.model.vo.SysServerNodeVO;
import com.sudo.service.admin.service.AdminBaseService;
import com.sudo.service.admin.service.SysInfoService;
import com.sudo.service.admin.service.SysServerNodeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SysServerNodeServiceImpl extends AdminBaseService implements SysServerNodeService {

    @Resource
    private SysServerNodeMapper sysServerNodeMapper;

    @Resource
    private SysInfoService sysInfoService;

    /**
     * 根据server查询服务器节点
     * @param server 唯一
     * @return 实体
     */

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public SysServerNode getServerNodeByServer(String server) {
        Example example = new Example(SysServerNode.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(SysServerNode.Field.server, server);
        return sysServerNodeMapper.selectOneByExample(example);
    }

    /**
     * 根据主键获取实体
     * @param id
     * @return
     */

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public SysServerNode getServerNodeById(Integer id) {
        return sysServerNodeMapper.selectByPrimaryKey(id);
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    @Override
    public PagedGridResult querySysServerNodeByPage(SysServerNodeQueryBO sysServerNodeQueryBO) {
        PageHelper.startPage(sysServerNodeQueryBO.getPage(), sysServerNodeQueryBO.getLimit());
        Example example = new Example(SysServerNode.class);
        example.orderBy(SysServerNode.Field.id).desc();
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(sysServerNodeQueryBO.getServer())) {
            criteria.andLike(SysServerNode.Field.server,"%"+sysServerNodeQueryBO.getServer()+"%");
        }
        if (StringUtils.isNotBlank(sysServerNodeQueryBO.getType())) {
            criteria.andEqualTo(SysServerNode.Field.type,sysServerNodeQueryBO.getType());
        }
        if (StringUtils.isNotBlank(sysServerNodeQueryBO.getStatus())) {
            criteria.andEqualTo(SysServerNode.Field.status,sysServerNodeQueryBO.getStatus());
        }
        List<SysServerNode> sysShellJobList = sysServerNodeMapper.selectByExample(example);
        return setterPagedGrid(sysShellJobList, sysServerNodeQueryBO.getPage());
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public List<SysServerNode> queryAllServerNodes() {
        return sysServerNodeMapper.selectAll();
    }

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public List<SysServerNodeVO> queryAllServerNodeInfo() {
        List<SysServerNode> sysServerNodeList = sysServerNodeMapper.selectAll();
        List<SysInfo> sysInfoList = sysInfoService.getSysInfoByCode(cpuCode, memCode);

        Map<String, String> sysInfoMap = new HashMap<>();
        sysInfoList.forEach(s-> sysInfoMap.put(s.getServer() + ":" + s.getCode(), s.getInfo()));
        List<SysServerNodeVO> sysServerNodeVOList = new ArrayList<>();
        sysServerNodeList.forEach(s->{
            SysServerNodeVO sysServerNodeVO = new SysServerNodeVO();
            BeanUtils.copyProperties(s, sysServerNodeVO);
            sysServerNodeVO.setCpu(sysInfoMap.get(s.getServer() + ":" + cpuCode));
            sysServerNodeVO.setMem(sysInfoMap.get(s.getServer() + ":" + memCode));
            sysServerNodeVOList.add(sysServerNodeVO);
        });
        return sysServerNodeVOList;
    }


    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public int saveServerNode(SysServerNodeSaveBO sysServerNodeSaveBO) {
        SysServerNode sysServerNode = new SysServerNode();
        BeanUtils.copyProperties(sysServerNodeSaveBO, sysServerNode);
        sysServerNode.setStatus(SysServerStatus.OFFLINE.name());
        sysServerNode.setStatusUpdateTime(LocalDateTime.now());

        return sysServerNodeMapper.insertSelective(sysServerNode);
    }


    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public int updateServerNode(SysServerNodeUpdateBO sysServerNodeUpdateBO) {
        SysServerNode sysServerNode = new SysServerNode();
        BeanUtils.copyProperties(sysServerNodeUpdateBO,sysServerNode);

        Example example = new Example(SysServerNode.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(SysServerNode.Field.server, sysServerNodeUpdateBO.getServer());
        return sysServerNodeMapper.updateByExampleSelective(sysServerNode,example);
    }

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public int updateServerNodeStatus(String server, String status) {
        SysServerNode sysServerNode = new SysServerNode();
        sysServerNode.setStatus(status);
        sysServerNode.setStatusUpdateTime(LocalDateTime.now());
        Example example = new Example(SysServerNode.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(SysServerNode.Field.server, server);
        return sysServerNodeMapper.updateByExampleSelective(sysServerNode,example);
    }

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public int deleteAndSaveServerNode(String server) {
        Example example = new Example(SysServerNode.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(SysServerNode.Field.server, server);
        sysServerNodeMapper.deleteByExample(example);

        SysServerNode sysServerNode = new SysServerNode();
        sysServerNode.setServer(server);
        sysServerNode.setType(SysServerType.AUTO.name());
        sysServerNode.setStatus(SysServerStatus.ONLINE.name());
        sysServerNode.setStatusUpdateTime(LocalDateTime.now());
        return sysServerNodeMapper.insertSelective(sysServerNode);
    }

    @Override
    public int deleteServerNode(Integer id) {
        return sysServerNodeMapper.deleteByPrimaryKey(id);
    }
}
